/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.platform.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.security.comment.constants.SecurityConstants;
import com.yami.shop.security.comment.model.AppConnect;
import com.yami.shop.security.comment.service.AppConnectService;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.UserService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;


/**
 * 商家详细信息
 * @author yami
 */
@RestController
@AllArgsConstructor
@RequestMapping("/platform/shopDetail")
public class ShopDetailController {

    private final ShopDetailService shopDetailService;
    private final OfflineHandleEventService offlineHandleEventService;
    private final AppConnectService appConnectService;
    private final TokenStore tokenStore;
    private final UserService userService;

    /**
     * 通过活动id获取下线信息
     */
    @GetMapping("/getOfflineHandleEventByShopId/{shopId}")
    @PreAuthorize("@pms.hasPermission('shop:shopAuditing:info')")
    public ResponseEntity<OfflineHandleEvent> getOfflineHandleEventByShopId(@PathVariable("shopId") Long shopId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.SHOP.getValue(), shopId);
        return ResponseEntity.ok(offlineHandleEvent);
    }

    /**
     * 下线活动
     */
    @PostMapping("/offline")
    @PreAuthorize("@pms.hasPermission('shop:shopAuditing:audit')")
    public ResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) {
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(offlineHandleEvent.getHandleId());
        if (shopDetail == null) {
            // 未找到该店铺信息
            throw new YamiShopBindException("yami.store.not.exist");
        }
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            // 店铺不处于营业状态,不能进行下线
            throw new YamiShopBindException("yami.store.offline.check");
        }
        shopDetailService.offline(shopDetail, offlineHandleEvent.getOfflineReason(), sysUserId);

        // 清除用户登陆token
        User user = userService.getUserByUserId(shopDetail.getUserId());
        if (!Objects.isNull(user)) {
            List<AppConnect> appConnects = appConnectService.list(new LambdaQueryWrapper<AppConnect>().eq(AppConnect::getUserId, user.getUserId()));
            if (CollectionUtils.isNotEmpty(appConnects)) {
                for (AppConnect appConnect : appConnects) {
                    // 移除登录成功的验证缓存
                    Map<String, String> values = new LinkedHashMap<>();
                    values.put("username", appConnect.getAppId() + StrUtil.COLON + appConnect.getBizUserId());
                    values.put("client_id", "null");
                    values.put("scope", "");
                    String key = SecurityConstants.YAMI_OAUTH_PREFIX + "auth_to_access:" + generateKey(values);
                    RedisUtil.del(key);
                    // 移除token校验的缓存
                    Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientIdAndUserName(StrUtil.NULL, appConnect.getAppId() + StrUtil.COLON + appConnect.getBizUserId());
                    for (OAuth2AccessToken token : tokens) {
                        RedisUtil.del(SecurityConstants.YAMI_OAUTH_PREFIX + "access:" + token.getValue());
                    }
                }
            }
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 店铺审核重新开店
     */
    @PostMapping("/auditShop")
    @PreAuthorize("@pms.hasPermission('shop:shopAuditing:audit')")
    public ResponseEntity<Void> auditOfflineShop(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Long sysUserId = SecurityUtils.getSysUser().getUserId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(offlineHandleEventAuditParam.getHandleId());
        if (shopDetail == null) {
            // 未找到店铺信息
            throw new YamiShopBindException("yami.store.not.exist");
        }
        shopDetailService.auditOfflineShop(offlineHandleEventAuditParam, sysUserId);

        return ResponseEntity.ok().build();
    }

    private String generateKey(Map<String, String> values) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
            byte[] bytes = digest.digest(values.toString().getBytes(StandardCharsets.UTF_8));
            return String.format("%032x", new BigInteger(1, bytes));
        } catch (NoSuchAlgorithmException nsae) {
            throw new IllegalStateException("MD5 algorithm not available.  Fatal (should be in the JDK).", nsae);
        }
    }

}
